<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
        <link rel="stylesheet" href="./banner.css" />
    </head>
    <body>
        <div class="banner">
            <ul class="imgBox clearFix">
                <li style="background-color: red">1</li>
                <li style="background-color: orange">2</li>
                <li style="background-color: green">3</li>
                <li style="background-color: pink">4</li>
                <li style="background-color: yellow">5</li>
            </ul>

            <!-- 指示器存放处 -->
            <ol class="pointBox"></ol>

            <div class="leftRightTabs">
                <a href="javascritp:;" class="left"><</a>
                <a href="javascritp:;" class="right">></a>
            </div>
        </div>
        <script>
            // 最外层的盒子
            const bannerBox = document.querySelector(".banner");

            // 幻灯片slider所在的盒子 ul
            const imgBox = bannerBox.querySelector("ul");

            // 指示器容器
            const pointerBox = bannerBox.querySelector("ol");

            // 左右按钮
            const leftRightTabs = bannerBox.querySelector(".leftRightTabs");

            // 全部滑动页
            const sliders = document.querySelectorAll("ul>li");
            const boxWidth = parseInt(
                window.getComputedStyle(sliders[0]).width
            );

            /* 自动播放 */

            /* 拷贝sliders的头尾两个元素 1 5 */
            // 拷贝一个1
            var rightInsertNode = sliders[0].cloneNode(true)
            // 拷贝一个5
            var leftInsertNode = sliders[sliders.length-1].cloneNode(true)

            // 把新拷贝出来的1插到原来5的右边
            imgBox.appendChild(rightInsertNode)

            // 把拷贝的5插到原来的1的左边
            imgBox.insertBefore(leftInsertNode,imgBox.children[0])

            // 重新设置一下UL的宽度 令其能包裹所有slider
            imgBox.style.width = imgBox.children.length * boxWidth + "px"

            // 每2000毫秒轮播一次
            let interval = 2000;

            /* 每2000毫秒向右滚动一下 相当于点击了向右按钮*/
            setInterval(() => {
                moveRight();
            }, interval);

            /* 动画结束回调函数 */
            function onMoveEnd(){
                // 更新指示器的高亮位置
                updatePointer()

                /* 
                当index来到6的时候 显示的是队尾的1 静默地将其置换为1号位置的1
                5 【1】 2 3 4 5 【1】
                   ↑-------------↑
                */
                if(index===6){
                    // 序号干回1（又可以接着往大浪了）
                    index = 1

                    // 静默地 瞬间完成切换
                    imgBox.style.left = -boxWidth * index + "px"
                }
            }

            leftRightTabs.onclick = function (e) {
                if (e.target.className === "left") {
                    // console.log("left");
                    moveLeft();
                }
                if (e.target.className === "right") {
                    // console.log("right");
                    moveRight();
                }
            };

            let index = 1;
            function moveLeft() {
                index--;
                index = index < 0 ? 0 : index;

                // 调用动画 动画结束时回调updatePointer方法 刷新指示器高亮位置
                // imgBox.style.left = -boxWidth * index + "px";
                move(imgBox, "left", -boxWidth * index, onMoveEnd);
            }

            function moveRight() {
                index++;
                index = index > 6 ? 6 : index;

                // 调用动画 动画结束时回调updatePointer方法 刷新指示器高亮位置
                // imgBox.style.left = -boxWidth * index + "px";
                move(imgBox, "left", -boxWidth * index, onMoveEnd);
            }

            /* 
            element     要做动画的 元素
            attr        要做动画的属性
            target      目标属性值
            callback    当动画完成时回调的函数
            */
            function move(element, attr, target, callback) {
                let currentValue = parseInt(
                    window.getComputedStyle(element)[attr]
                );
                let speed = (target - currentValue) / 50;

                let animTimer = setInterval(() => {
                    currentValue += speed;
                    element.style[attr] = currentValue + "px";

                    if (parseInt(element.style[attr]) === target) {
                        clearInterval(animTimer);

                        // callback && callback()
                        if (callback) {
                            callback();
                        }
                    }
                }, 20);
            }

            /* 指示器 一排可以点击的小圆点 */

            // 为每个滑动页slider配置一个指示器pointer
            sliders.forEach((silider, index) => {
                // 创建一个LI元素并丢入pointerBox中（CSS样式已经提前预设好了）
                var pointer = document.createElement("li");

                // 每个pointer与滑动页的index一一对应
                pointer.setAttribute("index", index);

                // 将当前的指示器LI添加到pointerBox这个OL中
                pointerBox.appendChild(pointer);

                // 将第一个小圆点高亮（因为默认选中第一张幻灯片）
                if (index === 0) {
                    pointer.classList.add("active");
                }
            });

            // 给OL设置宽度，让pointer之间有一定空隙（CSS样式已经提前预设好了）
            pointerBox.style.width = sliders.length * 20 + "px";

            // 将每个pointer的点击事件交给父元素pointerBox代理
            pointerBox.onclick = function (e) {
                // 如果点击的末梢是一个LI（点击了指示器）
                if (e.target.nodeName === "LI") {
                    // 取出该指示器的index
                    let targetIndex = e.target.getAttribute("index");
                    // 并滑动到对应的滑动页
                    moveTo(targetIndex);
                }
            };

            /* 一步到位地跳到指定页面 */
            function moveTo(n) {
                // 设好index
                index = n;

                // 调用动画设置imgBox的正确位置
                // 动画结束之后 回调updatePointer()刷新指示器的高亮位置
                move(imgBox, "left", -boxWidth * index, onMoveEnd);
            }

            /* 刷新指示器的高亮位置 */
            function updatePointer() {
                // // 遍历pointerBox中的全部pointer 全部取消active
                // for (let i = 0; i < pointerBox.children.length; i++) {
                //     // 拿到第I个LI/pointer
                //     let pointer = pointerBox.children[i];

                //     // 取消高亮
                //     pointer.classList.remove("active");
                // }

                // // 根据当前index找到正确的pointer 并激活
                // pointerBox.children[index].classList.add("active");
            }
        </script>
    </body>
</html>
